package org.wwc;

import java.util.*;
import java.util.function.*;
import java.util.stream.Collectors;

public class StreamDemo {

	public static void main(String[] args) throws Throwable {
		// 获取初始化数据
		List<Author> authors = getAuthors();

		// 1，打印所有年龄小于18的作者名字，并且去重复
		// authors.stream()
		// 		.filter(author -> author.getAge() < 18)
		// 		.distinct()
		// 		.forEach(author -> System.out.println(author.getName()));

		// 2，打印所有作者名字长度大于2的作家名字
		// authors.stream()
		// 		.filter(author -> author.getName().length() > 2)
		// 		.forEach(author -> System.out.println(author.getName()));

		// 3，打印所有作者名字
		// authors
		// 		.forEach(author -> System.out.println(author.getName()));

		// 4，给每个作者的年龄+5
		// authors.stream()
		// 		.map(author -> author.getAge()+5)
		// 		.forEach(System.out::println);

		// 5，打印所有作者的名称，并且不能有重复
		// authors.stream()
		// 		.distinct()
		// 		.forEach(author -> System.out.println(author.getName()));

		// 6，按照年龄对作者排序，并且不能重复
		// authors.stream()
		// 		.distinct()
		// 		.sorted((o1, o2) -> o2.getAge()- o1.getAge())
		// 		.forEach(author -> System.out.println(author.getAge()));

		// 7，只获取前2个不重复的作者列表
		// authors.stream()
		// 		.distinct()
		// 		.limit(2)
		// 		.forEach(author -> System.out.println(author.getName()));

		// 8，跳过前1个获取剩下的作者列表
		// authors.stream()
		// 		.distinct()
		// 		.skip(1)
		// 		.forEach(author -> System.out.println(author.getName()));

		// 9，获取所有的书籍
		// authors.stream()
		// 		.flatMap(author -> author.getBooks().stream())
		// 		.distinct()
		// 		.forEach(book -> System.out.println(book.getName()));

		// 10，获取所有的书籍分类，不能重复，并且不能包含'厨具',并且一列只显示一条分类
		// authors.stream()
		// 		.flatMap(author -> author.getBooks().stream())
		// 		.distinct()
		// 		.flatMap(book -> Arrays.stream(book.getCategory().split(",")))
		// 		.distinct()
		// 		.filter(s -> !"厨具".equals(s))
		// 		.forEach(System.out::println);

		// 11，打印所有的书籍名称
		// authors.stream()
		// 		.flatMap(author -> author.getBooks().stream())
		// 		.distinct()
		// 		.forEach(book -> System.out.println(book.getName()));

		// 12，统计所有不重复书名的个数
		// long count = authors.stream()
		// 		.flatMap(author -> author.getBooks().stream())
		// 		.distinct()
		// 		.count();
		// System.out.println(count);

		// 13，分别获取书籍最高分和最低分，并且打印
		// Optional<Integer> max = authors.stream()
		// 		.flatMap(author -> author.getBooks().stream())
		// 		.map(Book::getScore)
		// 		.max((score1, score2) -> score1 - score2);
		// max.ifPresent(System.out::println);
		//
		// Optional<Integer> min = authors.stream()
		// 		.flatMap(author -> author.getBooks().stream())
		// 		.map(Book::getScore)
		// 		.min((score1, score2) -> score1 - score2);
		// min.ifPresent(System.out::println);

		// 14，获取存放所有作者名字的集合
		// // list集合
		// List<String> collect1 = authors.stream()
		// 		.map(Author::getName)
		// 		.collect(Collectors.toList());
		// collect1.forEach(System.out::println);
		// // set集合
		// Set<String> collect2 = authors.stream()
		// 		.map(Author::getName)
		// 		.collect(Collectors.toSet());
		// collect2.forEach(System.out::println);
		// map集合 key为作者名，value为books
		// Map<String, List<Book>> collect3 = authors.stream()
		// 		.distinct()
		// 		.collect(Collectors.toMap(Author::getName, Author::getBooks));
		// collect3.entrySet()
		// 		.forEach(System.out::println);

		// 15，判断是否有年龄大于18的作者
		// boolean b = authors.stream()
		// 		.anyMatch(author -> author.getAge() > 18);
		// System.out.println(b);

		// 16，判断是否所有作者年龄都大于16
		// boolean b1 = authors.stream()
		// 		.allMatch(author -> author.getAge() > 16);
		// System.out.println(b1);

		// 17，获取任意一个年龄大于16的作者，并且打印他的名字
		// Optional<Author> a1 = authors.stream()
		// 		.filter(author -> author.getAge() > 16)
		// 		.findAny();
		// a1.ifPresent(author -> System.out.println(author.getName()));

		// 18，获取第一个作者的名字
		// Optional<Author> a2 = authors.stream()
		// 		.findFirst();
		// a2.ifPresent(author -> System.out.println(author.getName()));

		// 19，获取所有作者年龄的和
		// Integer reduce = authors.stream()
		// 		.distinct()
		// 		.map(Author::getAge)
		// 		.reduce(0, Integer::sum);
		// System.out.println(reduce);

		// 20，获取所有作者中年龄最大值
		// Integer reduce1 = authors.stream()
		// 		.distinct()
		// 		.map(Author::getAge)
		// 		.reduce(Integer.MIN_VALUE, (result, age) -> age > result ? age : result);
		// System.out.println(reduce1);

		// 21，获取所有作者中年龄最小值
		// Integer reduce2 = authors.stream()
		// 		.distinct()
		// 		.map(Author::getAge)
		// 		.reduce(Integer.MAX_VALUE, (result, age) -> age < result ? age : result);
		// System.out.println(reduce2);

		// Optional<Integer> reduce3 = authors.stream()
		// 		.distinct()
		// 		.map(Author::getAge)
		// 		.reduce((result, age) -> age < result ? age : result);
		// System.out.println(reduce3.orElseThrow(Exception::new));

		// 22，获取所有作者中年龄大于16，名字长度大于2的作者
		// authors.stream()
		// 		.filter(new Predicate<Author>() {
		// 			@Override
		// 			public boolean test(Author author) {
		// 				return author.getAge() > 16;
		// 			}
		// 		}.and(new Predicate<Author>() {
		// 			@Override
		// 			public boolean test(Author author) {
		// 				return author.getName().length() > 2;
		// 			}
		// 		}))
		// 		.forEach(System.out::println);

		// 23，获取所有作者中年龄大于18或者名字长度大于2的作者
		// authors.stream()
		// 		.filter(new Predicate<Author>() {
		// 			@Override
		// 			public boolean test(Author author) {
		// 				return author.getAge() > 18;
		// 			}
		// 		}.or(new Predicate<Author>() {
		// 			@Override
		// 			public boolean test(Author author) {
		// 				return author.getName().length() > 2;
		// 			}
		// 		}))
		// 		.forEach(System.out::println);

		// 24，获取所有作者中年龄不大于18的作者
		// authors.stream().parallel()
		// 		.filter(new Predicate<Author>() {
		// 			@Override
		// 			public boolean test(Author author) {
		// 				return author.getAge() > 18;
		// 			}
		// 		}.negate())
		// 		.forEach(System.out::println);





	}

	/**
	 * 初始化一些数据
	 * @return List<Author>
	 */
	private static List<Author> getAuthors() {
		// 作者数据
		Author author1 = new Author(1L, "蒙多", 18, "我是手握菜刀的祖安哲学家！", null);
		Author author2 = new Author(2L, "亚索", 19, "疾风亦有归途！", null);
		Author author3 = new Author(3L, "易大师", 17, "我的剑，就是你的剑！", null);
		Author author4 = new Author(3L, "易大师", 17, "我的剑，就是你的剑！", null);

		// 书数据
		List<Book> books1 = new ArrayList<>();
		List<Book> books2 = new ArrayList<>();
		List<Book> books3 = new ArrayList<>();
		List<Book> books4 = new ArrayList<>();

		// 上面是和书
		books1.add(new Book(1L, "菜刀的十八种用法", "厨具", 92, "菜刀的用法介绍"));
		books1.add(new Book(2L, "菜刀保养全篇", "厨具", 91, "菜刀的保养介绍"));
		books1.add(new Book(3L, "哲学家的意义", "哲学,爱情", 82, "哲学家的意义在哪？"));

		books2.add(new Book(5L, "风", "自然", 80, "暂无简介"));
		books2.add(new Book(6L, "归途", "哲学,爱情", 76, "我们人生的归途在哪里"));

		books3.add(new Book(7L, "剑法基础", "剑法,修炼", 96, "剑法基础学习"));
		books3.add(new Book(8L, "剑法高级", "剑法,修炼", 91, "剑法高级学习"));
		books3.add(new Book(9L, "人的一生", "哲学", 72, "什么是人生的意义，我们为什么出现"));

		books4.add(new Book(7L, "剑法基础", "剑法,修炼", 96, "剑法基础学习"));
		books4.add(new Book(8L, "剑法高级", "剑法,修炼", 91, "剑法高级学习"));
		books4.add(new Book(9L, "人的一生", "哲学", 72, "什么是人生的意义，我们为什么出现"));

		author1.setBooks(books1);
		author2.setBooks(books2);
		author3.setBooks(books3);
		author4.setBooks(books4);

		return new ArrayList<>(Arrays.asList(author1, author2, author3, author4));
	}
}
